/* WiFi station Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.h"

#include "driver/gpio.h"
#include "driver/uart.h"
#include "m_http_client.h"
#include "m_uart.h"
#include "m_config.h"

static const char *TAG = "M_UART";



extern xQueueHandle app_data_queue;


// uart
#define BUF_SIZE (2048)
#define RD_BUF_SIZE (BUF_SIZE)
static QueueHandle_t uart1_queue;

static uint8_t initCnt = 0;

void mmware_hardware_reset(void)
{
    gpio_pad_select_gpio(15);
    gpio_set_direction(15, GPIO_MODE_OUTPUT);
    gpio_set_level(15, 0);  // power pin 拉低2s
    vTaskDelay(500 / portTICK_PERIOD_MS);
    gpio_set_level(15, 1);
}


/*******************************************************************************
 ** \fn		uart_event_task
 ** \brief	ec600S 串口RX处理函数
 ******************************************************************************/
static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    size_t buffered_size;
    uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
    char pdtmp[256];
    for(;;) {
        //Waiting for UART event.
        if(xQueueReceive(uart1_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
            bzero(dtmp, RD_BUF_SIZE);
            memset(pdtmp,0,256);
            //ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_1);
            switch(event.type) 
            {
                case UART_DATA:
                    // ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
                    uart_read_bytes(UART_NUM_1, dtmp, event.size, portMAX_DELAY);
                    // for (size_t i = 0; i < event.size; i++)
                    // {
                    //     printf("%c",dtmp[i]);
                    // }
                    // printf("\r\n");

                    // ESP_LOGI(TAG, "[DATA EVT]:");
                    // uart_write_bytes(UART_NUM_1, (const char*) dtmp, event.size);
                    pdtmp[0] = event.size;
                    memcpy(pdtmp+1,dtmp,event.size);
                    //printf("SIZE:%d\r\n",pdtmp[0]);
                    if((pdtmp[1] == 0xA3 && pdtmp[2] == 0xA3)||(pdtmp[1]== 0xA4&&pdtmp[2]== 0xA4)||(pdtmp[event.size] == 0xB3 && pdtmp[event.size-1] == 0xB3))
                    {
                        xQueueSend(app_data_queue,pdtmp,NULL);
                    }

                    if(strstr((char*)dtmp,"<EOF>"))
                    {
                        //printf("scan start -1\r\n");
                        ESP_LOGW(TAG, "scan start -1");
                        //char at_cmd[15] = "scan start -1\r\n";
                        //uart_write_bytes(UART_NUM_1, at_cmd, 15);
                        #ifdef usr_use_position_or_heartbreath
                        char at_cmd[28] = { 0xA9 ,0xA9 ,0x42 ,0x00 ,0x12 ,0x00 ,0x00 ,0x00 ,
                                            0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
                                            0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
                                            0x54 ,0x00 ,0xB9 ,0xB9 };
                        #else
                        char at_cmd[28] = { 0xA9 ,0xA9 ,0x05 ,0x00 ,0x0C ,0x00 ,0x00 ,0x00 ,
                                            0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
                                            0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,
                                            0x11 ,0x00 ,0xB9 ,0xB9 };
                        #endif
                        uart_write_bytes(UART_NUM_1, at_cmd, 28);
                    }
                    break;
                //Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    //ESP_LOGI(TAG, "hw fifo overflow");
                    uart_flush_input(UART_NUM_1);
                    xQueueReset(uart1_queue);
                    break;
                //Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    ESP_LOGI(TAG, "ring buffer full");
                    uart_flush_input(UART_NUM_1);
                    xQueueReset(uart1_queue);
                    break;
                default:
                    ESP_LOGI(TAG, "uart event type: %d", event.type);
                    break;
            }
        }
    }
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
}

void uart_init(void)
{
    const uart_config_t uart_config = {
		.baud_rate = 3000000,
		.data_bits = UART_DATA_8_BITS,
		.parity = UART_PARITY_DISABLE,
		.stop_bits = UART_STOP_BITS_1,
		.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
		};

	uart_param_config(UART_NUM_1, &uart_config);
	uart_set_pin(UART_NUM_1, GPIO_NUM_13, GPIO_NUM_14, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

	uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 512, 20, &uart1_queue, 0);

    //Create a task to handler UART event from ISR
    xTaskCreate(uart_event_task, "uart_event_task", 4096, NULL, 5, NULL);
}

void mUart_init(void)
{
    ESP_LOGI(TAG, "ESP_UART_INIT");
    uart_init();
}

